<script setup>
import {reactive, ref, computed} from "vue"
import {INPUT_TYPE_EMAIL, INPUT_TYPE_TEXT} from "@/constant/tail_input_constant.js"
import {getMailCodeAPI, loginByMailAPI} from "@/api/login.js"
import {stringIsNull} from "@/utils/string_utils.js"
import useUserStore from '@/store/modules/user.js'

/**
 * 环境对象
 */
const env = import.meta.env

/**
 * userStore
 */
const userStore = useUserStore()

/**
 * 控制'获取验证码'按钮是否可用
 */
// 再次获取邮箱验证码所需等待的时间
const MAIL_CODE_AGAIN = Number.parseInt(env?.VITE_MAIL_CODE_AGAIN)
// 当前再次获取邮箱验证码还需等待的时间
const getMailCodeAgainWaitTime = ref(MAIL_CODE_AGAIN + 1)
// 倒计时定时器
let interval = null
// '获取验证码'按钮是否禁用
const getMailCodeBtnIsDisable = computed(() => {
  return getMailCodeAgainWaitTime.value <= MAIL_CODE_AGAIN
})
// '获取验证码'按钮是否为 loading 状态
const getMailCodeBtnIsLoading = ref(false)
// '获取验证码'按钮的文字内容
const getMailCodeBtnContent = computed(() => {
  if (getMailCodeBtnIsLoading.value) return '验证码获取中...'
  return getMailCodeBtnIsDisable.value ? `再次获取：${getMailCodeAgainWaitTime.value} s` : '获取验证码'
})

/**
 * 响应式存储用户登录信息
 */
const userLoginInfo = reactive({
  // 电子邮箱
  mail: '',
  // 验证码
  code: '',
})

/**
 * 获取邮箱验证码
 */
// 获取邮箱验证码
async function getMailCode() {
  // 验证用户输入的邮箱是否为空
  if (stringIsNull(userLoginInfo.mail)) {
    ElMessage({
      type: 'error',
      message: '请输入邮箱',
    })
    // 直接退出
    return
  }
  // 按钮为 loading 状态
  getMailCodeBtnIsLoading.value = true
  // 发送请求获取邮箱验证码
  const res = await getMailCodeAPI(userLoginInfo.mail)
  // 取消按钮的 loading 状态
  getMailCodeBtnIsLoading.value = false
  // 获取邮箱验证码失败，直接返回
  if (res !== true) {
    // 取消按钮的 loading 状态
    getMailCodeBtnIsLoading.value = false
    return
  }
  // 清除先前的定时器
  clearInterval(interval)
  // 直接先 -1 (原先多了 1)
  getMailCodeAgainWaitTime.value -= 1
  // 开启定时器
  interval = setInterval(() => {
    // 再次获取验证码所需等待时间 -1
    getMailCodeAgainWaitTime.value -= 1
    // 计时结束
    if (getMailCodeAgainWaitTime.value <= 0) {
      // 恢复
      getMailCodeAgainWaitTime.value = MAIL_CODE_AGAIN + 1
      // 清除定时器
      clearInterval(interval)
    }
  }, 1000)
}

/**
 * 控制'登录'按钮是否可用
 */
// 邮箱验证码的长度
const MAIL_CODE_LEN = Number.parseInt(env?.VITE_MAIL_CODE_LEN)
// 是否禁用登录按钮
const loginBtnIsDisable = computed(() => {
  return !(userLoginInfo.mail.length > 0 && userLoginInfo.code.length === MAIL_CODE_LEN)
})
// 登录按钮是否处于加载状态
const loginBtnIsLoading = ref(false)

/**
 * 登录
 */
async function login() {
  // 如果邮箱未输入
  if (stringIsNull(userLoginInfo.mail)) {
    ElMessage({
      type: 'error',
      message: '请输入邮箱',
    })
    return
  }
  // 如果未输入验证码
  if (stringIsNull(userLoginInfo.code)) {
    ElMessage({
      type: 'error',
      message: '请输入验证码',
    })
    return
  }
  // 输入的验证码长度不合法
  if (userLoginInfo.code.length !== MAIL_CODE_LEN) {
    ElMessage({
      type: 'error',
      message: '请正确输入验证码',
    })
    return
  }
  // 按钮为加载状态
  loginBtnIsLoading.value = true
  // 登录
  let res = null
  try {
    res = await loginByMailAPI(userLoginInfo.mail, userLoginInfo.code)
  } catch (e) {
    // 取消按钮的加载状态
    loginBtnIsLoading.value = false
    // 登录失败直接退出
    return
  }
  // 取消按钮的加载状态
  loginBtnIsLoading.value = false
  // 保存返回的登录信息
  userStore.saveUserinfo(res)
}
</script>

<template>
  <!-- 通过电子邮箱登录表单 -->
  <div class="login-form-by-email">
    <!-- 电子邮箱输入框 -->
    <TailInput
        class="login-form-input"
        :type="INPUT_TYPE_EMAIL"
        :placeholder="'请输入电子邮箱'"
        :font-size="'0.9rem'"
        :autofocus="true"
        v-model="userLoginInfo.mail"
        :maxlength="255"
        :enable-clear="userLoginInfo.mail.length > 0"
        @keydown.enter="getMailCode"
    >
      <!-- 输入框前缀图标 -->
      <template #preIcon>
        <span class="iconfont">&#xe6ff;</span>
      </template>
      <!-- 输入框清除图标 -->
      <template #clearIcon>
        <span class="iconfont">&#xe724;</span>
      </template>
    </TailInput>
    <!-- 验证码输入框 -->
    <TailInput
        ref="codeIptRef"
        class="login-form-input"
        :type="INPUT_TYPE_TEXT"
        :placeholder="'请输入验证码'"
        :font-size="'0.9rem'"
        v-model="userLoginInfo.code"
        :maxlength="6"
        :enable-clear="userLoginInfo.code.length > 0"
        @keydown.enter="login"
    >
      <!-- 输入框前缀图标 -->
      <template #preIcon>
        <span class="iconfont">&#xe63e;</span>
      </template>
      <!-- 输入框清除图标 -->
      <template #clearIcon>
        <span class="iconfont">&#xe724;</span>
      </template>
      <!-- 获取验证码按钮 -->
      <template #append>
        <el-button
            class="get-code-btn"
            type="primary"
            plain
            @click="getMailCode"
            :disabled="getMailCodeBtnIsDisable || getMailCodeBtnIsLoading"
            :loading="getMailCodeBtnIsLoading"
        >
          {{ getMailCodeBtnContent }}
        </el-button>
      </template>
    </TailInput>
    <!-- 登录按钮 -->
    <div class="login-btn">
      <el-button
          type="primary"
          :disabled="loginBtnIsDisable || loginBtnIsLoading"
          :loading="loginBtnIsLoading"
          @click="login"
      >{{ loginBtnIsLoading ? '登录中...' : '登录' }}
      </el-button>
    </div>
  </div>
</template>

<style scoped lang="scss">
/*
 * 通过电子邮箱登录表单
 */
.login-form-by-email {

  /*
   * 登录表单输入框
   */
  .login-form-input {
    width: var(--login-form-item-width);
    height: var(--login-form-item-height);
    margin-bottom: 1rem;

    /*
     * 获取验证码按钮
     */
    .get-code-btn {
      height: 100%;
    }
  }

  /*
   * 登录按钮
   */
  .login-btn {
    width: var(--login-form-item-width);
    height: var(--login-form-item-height);

    .el-button {
      width: 100%;
      height: 100%;
    }
  }
}
</style>